Import the data and split in train-set and test-set
library(haven)
data <- read_dta("data/zambia_height92.dta")
head(data)
#split data in train and test set
set.seed(123)
train <- sample(1:nrow(data), 0.85*nrow(data))
test <- setdiff(1:nrow(data), train)
train_data <- data[train,]
test_data <- data[test,]
Check for missing values (SPOILER: NO MISSING VALUES)
sum(is.na(train_data))
Cast of variables’ type
ggplotly(p)
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Now let’s dive into each variable.
First we plot the distribution of the zscore variable.
hist(train_data$zscore, breaks = 20, col = "lightblue", main = "Histogram of zscore", xlab = "zscore", freq = FALSE)
#add the normal curve with mean and sd of zscore
curve(dnorm(x, mean = mean(train_data$zscore), sd = sd(train_data$zscore)), col = "red", lwd = 2, add = TRUE)
#add the vertical dotted line at the mean, add it to the legend
abline(v = mean(train_data$zscore), col = "blue", lwd = 2, lty = 2)
legend("topright", c("Normal curve", "Mean"), col = c("red", "blue"), lwd = c(2, 2), lty = c(1, 2), cex = 1.5)
# Write the median and mean values to check if they're similar
text(350, 0.001, paste("Median:", round(median(train_data$zscore), 2), "\nMean:", round(mean(train_data$zscore), 2)), cex = 1.5)
Notice how this variable seems to follow a normal distribution. Also
the mean (and then the median) is significally lower than 0: this is a
measure of how the american population is healthier.
Let’s plot the correlation matrix for continuous variables
library(corrplot)
#correlation matrix for continuous variables
cor_matrix <- cor(train_data[,c("zscore", "c_breastf", "c_age", "m_agebirth", "m_height", "m_bmi")])
corrplot(cor_matrix, method = "circle", type = "upper", tl.col = "black", tl.srt = 45)
We would expect that the older the child gets, the higher the zscore.
This seems not true based on the correlation matrix. We will check this
later. This holds also for the amount of breasfeeding months.
Now we study the gender variable
#barplot of c_gender
table(train_data$c_gender)
The c_gender variable is quite balanced, even tho there are a bit
more females.
#plot the previous distribution (zscore) for c_gender=0 and c_gender=1
hist(train_data$zscore[train_data$c_gender==0], breaks = 20, col = rgb(0,0,1,1/4), main = "Histogram of zscore", xlab = "zscore", freq = FALSE)
hist(train_data$zscore[train_data$c_gender==1], breaks = 20, col = rgb(1,0,0,1/4), main = "Histogram of zscore", xlab = "zscore", freq = FALSE, add = TRUE)
# add the mean line for both distributions
abline(v = mean(train_data$zscore[train_data$c_gender==0]), col = "blue", lwd = 2, lty = 2)
abline(v = mean(train_data$zscore[train_data$c_gender==1]), col = "red", lwd = 2, lty = 2)

This has to be corrected on shiny, for now it’s sufficient to see
that the two distributions are quite similar.
#plot the distribution of the c_breastf variable
hist(train_data$c_breastf, breaks = 20, col = "lightblue", main = "Histogram of c_breastf", xlab = "c_breastf", freq = T)
There are a lot of children that have been breastfeed for 0
months.
library(ggplot2)
library(ggExtra)
#marginal plot of zscore and c_breastf
p <- ggplot(train_data, aes(x=c_breastf, y=zscore)) +
geom_point() +
theme(legend.position="none") +
# add a regression line
geom_smooth(method=lm, se=FALSE)
p1 <- ggMarginal(p, type="histogram")
p1
cor.test(train_data$zscore, train_data$c_breastf)
There doesn’t seem to be a correlation at eye, by looking at the
plot, but if we perform a test we can see that there is a slight
negative correlation between the variables, meaning that the more months
a child has been breastfed, the lower the zscore (quite odd)
library(dplyr)
#plot the marginal distribution of the zscore variable for c_breastf > 2
p <- train_data %>%
filter(c_breastf > 2) %>%
ggplot(., aes(x=c_breastf, y=zscore)) +
geom_point() +
theme(legend.position="none") +
# add a regression line
geom_smooth(method=lm, se=FALSE)
p2 <- ggMarginal(p, type="histogram")
p2
cor.test(train_data$zscore[train_data$c_breastf > 2], train_data$c_breastf[train_data$c_breastf > 2])
By removing the observations relatively to children that have been
breastfed for less than 2 months, we can see that the correlation is
very close to 0.
#plot the distribution of c_age variable
hist(train_data$c_age, breaks = 20, col = "lightblue", main = "Histogram of c_age", xlab = "c_age", freq = F)
#add a density curve
lines(density(train_data$c_age), col = "red", lwd = 2)
#marginal plot of zscore and c_age
p<- ggplot(train_data, aes(x=c_age, y=zscore)) +
geom_point() +
theme(legend.position="none") +
# add a regression line
geom_smooth(method=lm, se=FALSE)
p3 <- ggMarginal(p, type="histogram")
p3
We expect that the older the child, the higher the zscore, but the
plot doesn’t seem to show this. Let’s perform a test to see if there is
a correlation between the two variables.
cor.test(train_data$zscore, train_data$c_age)
#plot the distribution of m_agebirth variable
hist(train_data$m_agebirth, breaks = 20, col = "lightblue", main = "Histogram of m_agebirth", xlab = "m_agebirth", freq = F)
#add a density curve
lines(density(train_data$m_agebirth), col = "red", lwd = 2)
#add the mean line and the median line
abline(v = mean(train_data$m_agebirth), col = "blue", lwd = 2, lty = 2)
abline(v = median(train_data$m_agebirth), col = "green", lwd = 2, lty = 4)
#plot the distribution of m_height variable
hist(train_data$m_height, breaks = 20, col = "lightblue", main = "Histogram of m_height", xlab = "m_height", freq = F)
#add a normal distribution curve with the same mean and sd as the variable
curve(dnorm(x, mean = mean(train_data$m_height), sd = sd(train_data$m_height)), col = "red", lwd = 2, add = TRUE)
#add the mean line
abline(v = mean(train_data$m_height), col = "blue", lwd = 2, lty = 2)
#marginal plot of zscore and m_height
p<- ggplot(train_data, aes(x=m_height, y=zscore)) +
geom_point() +
theme(legend.position="none") +
# add a regression line
geom_smooth(method=lm, se=FALSE)
p4 <- ggMarginal(p, type="histogram")
p4
#plot the distribution of m_bmi variable
hist(train_data$m_bmi, breaks = 20, col = "lightblue", main = "Histogram of m_bmi", xlab = "m_bmi", freq = F)
#add a the density line
lines(density(train_data$m_bmi), col = "red", lwd = 2)
#add the mean line and median line
abline(v = mean(train_data$m_bmi), col = "blue", lwd = 2, lty = 2)
abline(v = median(train_data$m_bmi), col = "green", lwd = 2, lty = 4)
#marginal plot of zscore and m_bmi
p<- ggplot(train_data, aes(x=m_bmi, y=zscore)) +
geom_point() +
theme(legend.position="none") +
# add a regression line
geom_smooth(method=lm, se=FALSE)
p5 <- ggMarginal(p, type="histogram")
p5
Now we plot two histograms of the zscore, one for m_work = 0, and one
for m_work = 1, to see if there is a difference in the distribution of
the zscore between the two groups.
#table of the number of observations for each value of m_work
table(train_data$m_work)
#plot the previous distribution (zscore) for m_work=0 and m_workr=1
hist(train_data$zscore[train_data$m_work==0], breaks = 20, col = rgb(0,0,1,1/4), main = "Histogram of zscore", xlab = "zscore", freq = FALSE)
hist(train_data$zscore[train_data$m_work==1], breaks = 20, col = rgb(1,0,0,1/4), main = "Histogram of zscore", xlab = "zscore", freq = FALSE, add = TRUE)
For each value of the variable m_education, we plot the distribution
of the zscore.
par(mfrow=c(2,2))
#hist of zscore for each value of m_education
for (i in 1:4){
hist(train_data$zscore[train_data$m_education==i], breaks = 20, col = rgb(0,0,1,1/4), , xlab = "zscore", freq = FALSE)
}
NOTE: THIS PLOT WILL BE VERY DIFFERENT WITH R-SHINY, BECAUSE THE PLOT
IS INTERACTIVE
FOR REGION AND DISTRICTS CHECK CHOROPLETH MAPS FOR SHINY
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpJbXBvcnQgdGhlIGRhdGEgYW5kIHNwbGl0IGluIHRyYWluLXNldCBhbmQgdGVzdC1zZXQNCg0KYGBge3IgaW1wb3J0X2RhdGF9DQpsaWJyYXJ5KGhhdmVuKQ0KZGF0YSA8LSByZWFkX2R0YSgiZGF0YS96YW1iaWFfaGVpZ2h0OTIuZHRhIikNCmhlYWQoZGF0YSkNCg0KDQojc3BsaXQgZGF0YSBpbiB0cmFpbiBhbmQgdGVzdCBzZXQNCnNldC5zZWVkKDEyMykNCnRyYWluIDwtIHNhbXBsZSgxOm5yb3coZGF0YSksIDAuODUqbnJvdyhkYXRhKSkNCg0KdGVzdCA8LSBzZXRkaWZmKDE6bnJvdyhkYXRhKSwgdHJhaW4pDQoNCnRyYWluX2RhdGEgPC0gZGF0YVt0cmFpbixdDQp0ZXN0X2RhdGEgPC0gZGF0YVt0ZXN0LF0NCmBgYA0KDQpDaGVjayBmb3IgbWlzc2luZyB2YWx1ZXMgKFNQT0lMRVI6IE5PIE1JU1NJTkcgVkFMVUVTKQ0KDQpgYGB7ciBtaXNzaW5nX3ZhbHVlc30NCnN1bShpcy5uYSh0cmFpbl9kYXRhKSkNCmBgYA0KDQpDYXN0IG9mIHZhcmlhYmxlcycgdHlwZQ0KDQpgYGB7ciBjYXN0fQ0KI2NoZWNrIGlmIGFsbCB6c2NvcmUgdmFsdWVzIGFyZSBpbnRlZ2Vycw0Kc3VtKHRyYWluX2RhdGEkenNjb3JlIC0gYXMuaW50ZWdlcih0cmFpbl9kYXRhJHpzY29yZSkpDQoNCiNjYXN0IG9mIHpzY29yZSB0byBpbnRlZ2VyDQp0cmFpbl9kYXRhJHpzY29yZSA8LSBhcy5pbnRlZ2VyKHRyYWluX2RhdGEkenNjb3JlKQ0KDQojZmFjdG9yaXplIGdlbmRlcg0KdHJhaW5fZGF0YSRjX2dlbmRlciA8LSBhcy5mYWN0b3IodHJhaW5fZGF0YSRjX2dlbmRlcikNCg0KI2Nhc3QgY19icmVhc3RmIGFzIGludGVnZXINCnRyYWluX2RhdGEkY19icmVhc3RmIDwtIGFzLmludGVnZXIodHJhaW5fZGF0YSRjX2JyZWFzdGYpDQoNCiNjYXN0IGNfYWdlIGFzIGludGVnZXINCnRyYWluX2RhdGEkY19hZ2UgPC0gYXMuaW50ZWdlcih0cmFpbl9kYXRhJGNfYWdlKQ0KDQojTk9URTogdG8gaGF2ZSB0aGUgbW9udGggb2YgYmlydGggaW4gbV9hZ2ViaXJ0aCBjYWxjdWxhdGU6IGRlY2ltYWxfcGFydCAqIDEyDQoNCiNmYWN0b3JpemUgbV9lZHVjYXRpb24NCnRyYWluX2RhdGEkbV9lZHVjYXRpb24gPC0gYXMuZmFjdG9yKHRyYWluX2RhdGEkbV9lZHVjYXRpb24pDQoNCiNmYWN0b3JpemUgbV93b3JrDQp0cmFpbl9kYXRhJG1fd29yayA8LSBhcy5mYWN0b3IodHJhaW5fZGF0YSRtX3dvcmspDQoNCiNmYWN0b3JpemUgcmVnaW9uDQp0cmFpbl9kYXRhJHJlZ2lvbiA8LSBhcy5mYWN0b3IodHJhaW5fZGF0YSRyZWdpb24pDQoNCiNmYWN0b3JpemUgZGlzdHJpY3QNCnRyYWluX2RhdGEkZGlzdHJpY3QgPC0gYXMuZmFjdG9yKHRyYWluX2RhdGEkZGlzdHJpY3QpDQoNCnAgPC0gZ2dwbG90KHRyYWluX2RhdGEsIGFlcyh4ID0genNjb3JlLCB5ID0gYWZ0ZXJfc3RhdChjb3VudCAvIHN1bShjb3VudCkpKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShkYXRhID0gc3Vic2V0KHRyYWluX2RhdGEsIGNfZ2VuZGVyID09IDApLCBhZXMoZmlsbCA9ICJGZW1hbGUiKSwgY29sb3VyID0gJ2JsYWNrJykgKw0KICBnZW9tX2hpc3RvZ3JhbShkYXRhID0gc3Vic2V0KHRyYWluX2RhdGEsIGNfZ2VuZGVyID09IDEpLCBhZXMoZmlsbCA9ICJNYWxlIiksIGNvbG91ciA9ICdibGFjaycsIGFscGhhID0gMC41KSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWUgPSAiR2VuZGVyIiwgdmFsdWVzPWMoInBpbmsxIiwgInN0ZWVsYmx1ZTEiKSkgKw0KICBsYWJzKHRpdGxlID0gIkhpc3RvZ3JhbXMgb2YgenNjb3JlIGJ5IGdlbmRlciIsIHggPSAienNjb3JlIiwgeSA9IE5VTEwpDQoNCmdncGxvdGx5KHApDQpgYGANCg0KTm93IGxldCdzIGRpdmUgaW50byBlYWNoIHZhcmlhYmxlLg0KDQpGaXJzdCB3ZSBwbG90IHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHpzY29yZSB2YXJpYWJsZS4NCg0KYGBge3IgenNjb3JlfQ0KaGlzdCh0cmFpbl9kYXRhJHpzY29yZSwgYnJlYWtzID0gMjAsIGNvbCA9ICJsaWdodGJsdWUiLCBtYWluID0gIkhpc3RvZ3JhbSBvZiB6c2NvcmUiLCB4bGFiID0gInpzY29yZSIsIGZyZXEgPSBGQUxTRSkNCiNhZGQgdGhlIG5vcm1hbCBjdXJ2ZSB3aXRoIG1lYW4gYW5kIHNkIG9mIHpzY29yZQ0KY3VydmUoZG5vcm0oeCwgbWVhbiA9IG1lYW4odHJhaW5fZGF0YSR6c2NvcmUpLCBzZCA9IHNkKHRyYWluX2RhdGEkenNjb3JlKSksIGNvbCA9ICJyZWQiLCBsd2QgPSAyLCBhZGQgPSBUUlVFKQ0KI2FkZCB0aGUgdmVydGljYWwgZG90dGVkIGxpbmUgYXQgdGhlIG1lYW4sIGFkZCBpdCB0byB0aGUgbGVnZW5kDQphYmxpbmUodiA9IG1lYW4odHJhaW5fZGF0YSR6c2NvcmUpLCBjb2wgPSAiYmx1ZSIsIGx3ZCA9IDIsIGx0eSA9IDIpDQpsZWdlbmQoInRvcHJpZ2h0IiwgYygiTm9ybWFsIGN1cnZlIiwgIk1lYW4iKSwgY29sID0gYygicmVkIiwgImJsdWUiKSwgbHdkID0gYygyLCAyKSwgbHR5ID0gYygxLCAyKSwgY2V4ID0gMS41KQ0KIyBXcml0ZSB0aGUgbWVkaWFuIGFuZCBtZWFuIHZhbHVlcyB0byBjaGVjayBpZiB0aGV5J3JlIHNpbWlsYXIgDQp0ZXh0KDM1MCwgMC4wMDEsIHBhc3RlKCJNZWRpYW46Iiwgcm91bmQobWVkaWFuKHRyYWluX2RhdGEkenNjb3JlKSwgMiksICJcbk1lYW46Iiwgcm91bmQobWVhbih0cmFpbl9kYXRhJHpzY29yZSksIDIpKSwgY2V4ID0gMS41KQ0KYGBgDQoNCk5vdGljZSBob3cgdGhpcyB2YXJpYWJsZSBzZWVtcyB0byBmb2xsb3cgYSBub3JtYWwgZGlzdHJpYnV0aW9uLiBBbHNvIHRoZSBtZWFuIChhbmQgdGhlbiB0aGUgbWVkaWFuKSBpcyBzaWduaWZpY2FsbHkgbG93ZXIgdGhhbiAwOiB0aGlzIGlzIGEgbWVhc3VyZSBvZiBob3cgdGhlIGFtZXJpY2FuIHBvcHVsYXRpb24gaXMgaGVhbHRoaWVyLg0KDQpMZXQncyBwbG90IHRoZSBjb3JyZWxhdGlvbiBtYXRyaXggZm9yIGNvbnRpbnVvdXMgdmFyaWFibGVzDQoNCmBgYHtyIGNvcl9tYXRyaXh9DQpsaWJyYXJ5KGNvcnJwbG90KQ0KI2NvcnJlbGF0aW9uIG1hdHJpeCBmb3IgY29udGludW91cyB2YXJpYWJsZXMNCmNvcl9tYXRyaXggPC0gY29yKHRyYWluX2RhdGFbLGMoInpzY29yZSIsICJjX2JyZWFzdGYiLCAiY19hZ2UiLCAibV9hZ2ViaXJ0aCIsICJtX2hlaWdodCIsICJtX2JtaSIpXSkNCmNvcnJwbG90KGNvcl9tYXRyaXgsIG1ldGhvZCA9ICJjaXJjbGUiLCB0eXBlID0gInVwcGVyIiwgdGwuY29sID0gImJsYWNrIiwgdGwuc3J0ID0gNDUpDQpgYGANCldlIHdvdWxkIGV4cGVjdCB0aGF0IHRoZSBvbGRlciB0aGUgY2hpbGQgZ2V0cywgdGhlIGhpZ2hlciB0aGUgenNjb3JlLiBUaGlzIHNlZW1zIG5vdCB0cnVlIGJhc2VkIG9uIHRoZSBjb3JyZWxhdGlvbiBtYXRyaXguIFdlIHdpbGwgY2hlY2sgdGhpcyBsYXRlci4gVGhpcyBob2xkcyBhbHNvIGZvciB0aGUgYW1vdW50IG9mIGJyZWFzZmVlZGluZyBtb250aHMuDQoNCg0KDQoNCk5vdyB3ZSBzdHVkeSB0aGUgZ2VuZGVyIHZhcmlhYmxlDQoNCmBgYHtyIGdlbmRlcn0NCiNiYXJwbG90IG9mIGNfZ2VuZGVyDQp0YWJsZSh0cmFpbl9kYXRhJGNfZ2VuZGVyKQ0KYGBgDQoNClRoZSBjX2dlbmRlciB2YXJpYWJsZSBpcyBxdWl0ZSBiYWxhbmNlZCwgZXZlbiB0aG8gdGhlcmUgYXJlIGEgYml0IG1vcmUgZmVtYWxlcy4NCg0KYGBge3IgenNjb3JlX2dlbmRlcn0NCiNwbG90IHRoZSBwcmV2aW91cyBkaXN0cmlidXRpb24gKHpzY29yZSkgZm9yIGNfZ2VuZGVyPTAgYW5kIGNfZ2VuZGVyPTENCg0KaGlzdCh0cmFpbl9kYXRhJHpzY29yZVt0cmFpbl9kYXRhJGNfZ2VuZGVyPT0wXSwgYnJlYWtzID0gMjAsIGNvbCA9IHJnYigwLDAsMSwxLzQpLCBtYWluID0gIkhpc3RvZ3JhbSBvZiB6c2NvcmUiLCB4bGFiID0gInpzY29yZSIsIGZyZXEgPSBGQUxTRSkNCmhpc3QodHJhaW5fZGF0YSR6c2NvcmVbdHJhaW5fZGF0YSRjX2dlbmRlcj09MV0sIGJyZWFrcyA9IDIwLCBjb2wgPSByZ2IoMSwwLDAsMS80KSwgbWFpbiA9ICJIaXN0b2dyYW0gb2YgenNjb3JlIiwgeGxhYiA9ICJ6c2NvcmUiLCBmcmVxID0gRkFMU0UsIGFkZCA9IFRSVUUpDQoNCiMgYWRkIHRoZSBtZWFuIGxpbmUgZm9yIGJvdGggZGlzdHJpYnV0aW9ucw0KYWJsaW5lKHYgPSBtZWFuKHRyYWluX2RhdGEkenNjb3JlW3RyYWluX2RhdGEkY19nZW5kZXI9PTBdKSwgY29sID0gImJsdWUiLCBsd2QgPSAyLCBsdHkgPSAyKQ0KYWJsaW5lKHYgPSBtZWFuKHRyYWluX2RhdGEkenNjb3JlW3RyYWluX2RhdGEkY19nZW5kZXI9PTFdKSwgY29sID0gInJlZCIsIGx3ZCA9IDIsIGx0eSA9IDIpDQoNCmBgYA0KDQpUaGlzIGhhcyB0byBiZSBjb3JyZWN0ZWQgb24gc2hpbnksIGZvciBub3cgaXQncyBzdWZmaWNpZW50IHRvIHNlZSB0aGF0IHRoZSB0d28gZGlzdHJpYnV0aW9ucyBhcmUgcXVpdGUgc2ltaWxhci4NCg0KYGBge3IgY19icmVhc3RmfQ0KI3Bsb3QgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgY19icmVhc3RmIHZhcmlhYmxlDQpoaXN0KHRyYWluX2RhdGEkY19icmVhc3RmLCBicmVha3MgPSAyMCwgY29sID0gImxpZ2h0Ymx1ZSIsIG1haW4gPSAiSGlzdG9ncmFtIG9mIGNfYnJlYXN0ZiIsIHhsYWIgPSAiY19icmVhc3RmIiwgZnJlcSA9IFQpDQoNCmBgYA0KDQpUaGVyZSBhcmUgYSBsb3Qgb2YgY2hpbGRyZW4gdGhhdCBoYXZlIGJlZW4gYnJlYXN0ZmVlZCBmb3IgMCBtb250aHMuDQoNCmBgYHtyIHpzY29yZV9icmVhc3RmfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShnZ0V4dHJhKQ0KI21hcmdpbmFsIHBsb3Qgb2YgenNjb3JlIGFuZCBjX2JyZWFzdGYNCg0KcCA8LSBnZ3Bsb3QodHJhaW5fZGF0YSwgYWVzKHg9Y19icmVhc3RmLCB5PXpzY29yZSkpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgKw0KICAjIGFkZCBhIHJlZ3Jlc3Npb24gbGluZQ0KICBnZW9tX3Ntb290aChtZXRob2Q9bG0sIHNlPUZBTFNFKQ0KDQpwMSA8LSBnZ01hcmdpbmFsKHAsIHR5cGU9Imhpc3RvZ3JhbSIpDQoNCnAxDQpgYGANCg0KYGBge3IgY29yX3pzY29yZV9icmVhc3RmfQ0KY29yLnRlc3QodHJhaW5fZGF0YSR6c2NvcmUsIHRyYWluX2RhdGEkY19icmVhc3RmKQ0KYGBgDQoNClRoZXJlIGRvZXNuJ3Qgc2VlbSB0byBiZSBhIGNvcnJlbGF0aW9uIGF0IGV5ZSwgYnkgbG9va2luZyBhdCB0aGUgcGxvdCwgYnV0IGlmIHdlIHBlcmZvcm0gYSB0ZXN0IHdlIGNhbiBzZWUgdGhhdCB0aGVyZSBpcyBhIHNsaWdodCBuZWdhdGl2ZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRoZSB2YXJpYWJsZXMsIG1lYW5pbmcgdGhhdCB0aGUgbW9yZSBtb250aHMgYSBjaGlsZCBoYXMgYmVlbiBicmVhc3RmZWQsIHRoZSBsb3dlciB0aGUgenNjb3JlIChxdWl0ZSBvZGQpDQoNCmBgYHtyIHpzY29yZV9icmVhc3RmXzJ9DQpsaWJyYXJ5KGRwbHlyKQ0KI3Bsb3QgdGhlIG1hcmdpbmFsIGRpc3RyaWJ1dGlvbiBvZiB0aGUgenNjb3JlIHZhcmlhYmxlIGZvciBjX2JyZWFzdGYgPiAyDQoNCnAgPC0gdHJhaW5fZGF0YSAlPiUgDQogIGZpbHRlcihjX2JyZWFzdGYgPiAyKSAlPiUgDQogIGdncGxvdCguLCBhZXMoeD1jX2JyZWFzdGYsIHk9enNjb3JlKSkgKw0KICBnZW9tX3BvaW50KCkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArDQogICMgYWRkIGEgcmVncmVzc2lvbiBsaW5lDQogIGdlb21fc21vb3RoKG1ldGhvZD1sbSwgc2U9RkFMU0UpDQoNCnAyIDwtIGdnTWFyZ2luYWwocCwgdHlwZT0iaGlzdG9ncmFtIikNCg0KcDINCmBgYA0KDQpgYGB7ciBjb3JfenNjb3JlX2JyZWFzdGZfMn0NCmNvci50ZXN0KHRyYWluX2RhdGEkenNjb3JlW3RyYWluX2RhdGEkY19icmVhc3RmID4gMl0sIHRyYWluX2RhdGEkY19icmVhc3RmW3RyYWluX2RhdGEkY19icmVhc3RmID4gMl0pDQoNCmBgYA0KDQpCeSByZW1vdmluZyB0aGUgb2JzZXJ2YXRpb25zIHJlbGF0aXZlbHkgdG8gY2hpbGRyZW4gdGhhdCBoYXZlIGJlZW4gYnJlYXN0ZmVkIGZvciBsZXNzIHRoYW4gMiBtb250aHMsIHdlIGNhbiBzZWUgdGhhdCB0aGUgY29ycmVsYXRpb24gaXMgdmVyeSBjbG9zZSB0byAwLg0KDQpgYGB7ciBjX2FnZX0NCiNwbG90IHRoZSBkaXN0cmlidXRpb24gb2YgY19hZ2UgdmFyaWFibGUNCmhpc3QodHJhaW5fZGF0YSRjX2FnZSwgYnJlYWtzID0gMjAsIGNvbCA9ICJsaWdodGJsdWUiLCBtYWluID0gIkhpc3RvZ3JhbSBvZiBjX2FnZSIsIHhsYWIgPSAiY19hZ2UiLCBmcmVxID0gRikNCiNhZGQgYSBkZW5zaXR5IGN1cnZlDQpsaW5lcyhkZW5zaXR5KHRyYWluX2RhdGEkY19hZ2UpLCBjb2wgPSAicmVkIiwgbHdkID0gMikNCg0KYGBgDQoNCmBgYHtyIHpzY29yZV9hZ2V9DQojbWFyZ2luYWwgcGxvdCBvZiB6c2NvcmUgYW5kIGNfYWdlDQpwPC0gZ2dwbG90KHRyYWluX2RhdGEsIGFlcyh4PWNfYWdlLCB5PXpzY29yZSkpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgKw0KICAjIGFkZCBhIHJlZ3Jlc3Npb24gbGluZQ0KICBnZW9tX3Ntb290aChtZXRob2Q9bG0sIHNlPUZBTFNFKQ0KDQpwMyA8LSBnZ01hcmdpbmFsKHAsIHR5cGU9Imhpc3RvZ3JhbSIpDQpwMw0KDQpgYGANCldlIGV4cGVjdCB0aGF0IHRoZSBvbGRlciB0aGUgY2hpbGQsIHRoZSBoaWdoZXIgdGhlIHpzY29yZSwgYnV0IHRoZSBwbG90IGRvZXNuJ3Qgc2VlbSB0byBzaG93IHRoaXMuIExldCdzIHBlcmZvcm0gYSB0ZXN0IHRvIHNlZSBpZiB0aGVyZSBpcyBhIGNvcnJlbGF0aW9uIGJldHdlZW4gdGhlIHR3byB2YXJpYWJsZXMuDQpgYGB7ciBjb3JfenNjb3JlX2FnZX0NCmNvci50ZXN0KHRyYWluX2RhdGEkenNjb3JlLCB0cmFpbl9kYXRhJGNfYWdlKQ0KDQpgYGANCg0KDQoNCg0KYGBge3IgbV9hZ2ViaXJ0aH0NCiNwbG90IHRoZSBkaXN0cmlidXRpb24gb2YgbV9hZ2ViaXJ0aCB2YXJpYWJsZQ0KaGlzdCh0cmFpbl9kYXRhJG1fYWdlYmlydGgsIGJyZWFrcyA9IDIwLCBjb2wgPSAibGlnaHRibHVlIiwgbWFpbiA9ICJIaXN0b2dyYW0gb2YgbV9hZ2ViaXJ0aCIsIHhsYWIgPSAibV9hZ2ViaXJ0aCIsIGZyZXEgPSBGKQ0KI2FkZCBhIGRlbnNpdHkgY3VydmUNCmxpbmVzKGRlbnNpdHkodHJhaW5fZGF0YSRtX2FnZWJpcnRoKSwgY29sID0gInJlZCIsIGx3ZCA9IDIpDQojYWRkIHRoZSBtZWFuIGxpbmUgYW5kIHRoZSBtZWRpYW4gbGluZQ0KYWJsaW5lKHYgPSBtZWFuKHRyYWluX2RhdGEkbV9hZ2ViaXJ0aCksIGNvbCA9ICJibHVlIiwgbHdkID0gMiwgbHR5ID0gMikNCmFibGluZSh2ID0gbWVkaWFuKHRyYWluX2RhdGEkbV9hZ2ViaXJ0aCksIGNvbCA9ICJncmVlbiIsIGx3ZCA9IDIsIGx0eSA9IDQpDQoNCmBgYA0KYGBge3IgbV9oZWlnaHR9DQojcGxvdCB0aGUgZGlzdHJpYnV0aW9uIG9mIG1faGVpZ2h0IHZhcmlhYmxlDQpoaXN0KHRyYWluX2RhdGEkbV9oZWlnaHQsIGJyZWFrcyA9IDIwLCBjb2wgPSAibGlnaHRibHVlIiwgbWFpbiA9ICJIaXN0b2dyYW0gb2YgbV9oZWlnaHQiLCB4bGFiID0gIm1faGVpZ2h0IiwgZnJlcSA9IEYpDQojYWRkIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiBjdXJ2ZSB3aXRoIHRoZSBzYW1lIG1lYW4gYW5kIHNkIGFzIHRoZSB2YXJpYWJsZQ0KY3VydmUoZG5vcm0oeCwgbWVhbiA9IG1lYW4odHJhaW5fZGF0YSRtX2hlaWdodCksIHNkID0gc2QodHJhaW5fZGF0YSRtX2hlaWdodCkpLCBjb2wgPSAicmVkIiwgbHdkID0gMiwgYWRkID0gVFJVRSkNCiNhZGQgdGhlIG1lYW4gbGluZQ0KYWJsaW5lKHYgPSBtZWFuKHRyYWluX2RhdGEkbV9oZWlnaHQpLCBjb2wgPSAiYmx1ZSIsIGx3ZCA9IDIsIGx0eSA9IDIpDQoNCmBgYA0KDQpgYGB7ciB6c2NvcmVfdnNfbV9oZWlnaHR9DQojbWFyZ2luYWwgcGxvdCBvZiB6c2NvcmUgYW5kIG1faGVpZ2h0DQpwPC0gZ2dwbG90KHRyYWluX2RhdGEsIGFlcyh4PW1faGVpZ2h0LCB5PXpzY29yZSkpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgKw0KICAjIGFkZCBhIHJlZ3Jlc3Npb24gbGluZQ0KICBnZW9tX3Ntb290aChtZXRob2Q9bG0sIHNlPUZBTFNFKQ0KDQpwNCA8LSBnZ01hcmdpbmFsKHAsIHR5cGU9Imhpc3RvZ3JhbSIpDQpwNA0KDQpgYGANCmBgYHtyIG1fYm1pfQ0KI3Bsb3QgdGhlIGRpc3RyaWJ1dGlvbiBvZiBtX2JtaSB2YXJpYWJsZQ0KaGlzdCh0cmFpbl9kYXRhJG1fYm1pLCBicmVha3MgPSAyMCwgY29sID0gImxpZ2h0Ymx1ZSIsIG1haW4gPSAiSGlzdG9ncmFtIG9mIG1fYm1pIiwgeGxhYiA9ICJtX2JtaSIsIGZyZXEgPSBGKQ0KI2FkZCBhIHRoZSBkZW5zaXR5IGxpbmUNCmxpbmVzKGRlbnNpdHkodHJhaW5fZGF0YSRtX2JtaSksIGNvbCA9ICJyZWQiLCBsd2QgPSAyKQ0KI2FkZCB0aGUgbWVhbiBsaW5lIGFuZCBtZWRpYW4gbGluZQ0KYWJsaW5lKHYgPSBtZWFuKHRyYWluX2RhdGEkbV9ibWkpLCBjb2wgPSAiYmx1ZSIsIGx3ZCA9IDIsIGx0eSA9IDIpDQphYmxpbmUodiA9IG1lZGlhbih0cmFpbl9kYXRhJG1fYm1pKSwgY29sID0gImdyZWVuIiwgbHdkID0gMiwgbHR5ID0gNCkNCg0KYGBgDQoNCmBgYHtyIHpzY29yZV92c19tX2JtaX0NCiNtYXJnaW5hbCBwbG90IG9mIHpzY29yZSBhbmQgbV9ibWkNCnA8LSBnZ3Bsb3QodHJhaW5fZGF0YSwgYWVzKHg9bV9ibWksIHk9enNjb3JlKSkgKw0KICBnZW9tX3BvaW50KCkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArDQogICMgYWRkIGEgcmVncmVzc2lvbiBsaW5lDQogIGdlb21fc21vb3RoKG1ldGhvZD1sbSwgc2U9RkFMU0UpDQoNCnA1IDwtIGdnTWFyZ2luYWwocCwgdHlwZT0iaGlzdG9ncmFtIikNCnA1DQoNCmBgYA0KDQpOb3cgd2UgcGxvdCB0d28gaGlzdG9ncmFtcyBvZiB0aGUgenNjb3JlLCBvbmUgZm9yIG1fd29yayA9IDAsIGFuZCBvbmUgZm9yIG1fd29yayA9IDEsIHRvIHNlZSBpZiB0aGVyZSBpcyBhIGRpZmZlcmVuY2UgaW4gdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgenNjb3JlIGJldHdlZW4gdGhlIHR3byBncm91cHMuDQpgYGB7ciBtX3dvcmtfdGFibGV9DQojdGFibGUgb2YgdGhlIG51bWJlciBvZiBvYnNlcnZhdGlvbnMgZm9yIGVhY2ggdmFsdWUgb2YgbV93b3JrDQp0YWJsZSh0cmFpbl9kYXRhJG1fd29yaykNCg0KYGBgDQoNCg0KDQoNCmBgYHtyIG1fd29ya30NCiNwbG90IHRoZSBwcmV2aW91cyBkaXN0cmlidXRpb24gKHpzY29yZSkgZm9yIG1fd29yaz0wIGFuZCBtX3dvcmtyPTENCmhpc3QodHJhaW5fZGF0YSR6c2NvcmVbdHJhaW5fZGF0YSRtX3dvcms9PTBdLCBicmVha3MgPSAyMCwgY29sID0gcmdiKDAsMCwxLDEvNCksIG1haW4gPSAiSGlzdG9ncmFtIG9mIHpzY29yZSIsIHhsYWIgPSAienNjb3JlIiwgZnJlcSA9IEZBTFNFKQ0KaGlzdCh0cmFpbl9kYXRhJHpzY29yZVt0cmFpbl9kYXRhJG1fd29yaz09MV0sIGJyZWFrcyA9IDIwLCBjb2wgPSByZ2IoMSwwLDAsMS80KSwgbWFpbiA9ICJIaXN0b2dyYW0gb2YgenNjb3JlIiwgeGxhYiA9ICJ6c2NvcmUiLCBmcmVxID0gRkFMU0UsIGFkZCA9IFRSVUUpDQoNCmBgYA0KDQoNCkZvciBlYWNoIHZhbHVlIG9mIHRoZSB2YXJpYWJsZSBtX2VkdWNhdGlvbiwgd2UgcGxvdCB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSB6c2NvcmUuDQoNCmBgYHtyIG1fZWR1Y2F0aW9uX3RhYmxlfQ0KcGFyKG1mcm93PWMoMiwyKSkNCiNoaXN0IG9mIHpzY29yZSBmb3IgZWFjaCB2YWx1ZSBvZiBtX2VkdWNhdGlvbg0KZm9yIChpIGluIDE6NCl7DQogIGhpc3QodHJhaW5fZGF0YSR6c2NvcmVbdHJhaW5fZGF0YSRtX2VkdWNhdGlvbj09aV0sIGJyZWFrcyA9IDIwLCBjb2wgPSByZ2IoMCwwLDEsMS80KSwgLCB4bGFiID0gInpzY29yZSIsIGZyZXEgPSBGQUxTRSkNCn0NCg0KYGBgDQoNCk5PVEU6IFRISVMgUExPVCBXSUxMIEJFIFZFUlkgRElGRkVSRU5UIFdJVEggUi1TSElOWSwgQkVDQVVTRSBUSEUgUExPVCBJUyBJTlRFUkFDVElWRQ0KDQpGT1IgUkVHSU9OIEFORCBESVNUUklDVFMgQ0hFQ0sgQ0hPUk9QTEVUSCBNQVBTIEZPUiBTSElOWQ0KDQoNCg0KDQoNCg0KDQoNCg==